package com.scedu.aspect;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.context.annotation.Configuration;


@Aspect
@Configuration
@Slf4j
public class UserServiceAspect {
    //前置通知@Before
    @Before("within(com.scedu.service.Impl.*Impl)")
    public void before(JoinPoint joinPoint){
        log.info("目标方法名称："+joinPoint.getSignature().getName());
        log.info("目标方法参数："+joinPoint.getArgs());
        log.info("目标对象："+joinPoint.getTarget());
        log.info("前置通知");
    }

    //后置最终通知@After
    @After("within(com.scedu.service.Impl.*Impl)")
    public  void after(JoinPoint joinPoint){
        log.info("后置通知目标方法名称："+joinPoint.getSignature().getName());
        log.info("后置通知");

    }
    //环绕通知@Around
    /**
     * 环绕通知：
     *   环绕通知非常强大，可以决定目标方法是否执行，什么时候执行，执行时是否需要替换方法参数，执行完毕是否需要替换返回值。
     *   环绕通知第一个参数必须是org.aspectj.lang.ProceedingJoinPoint类型
     */
    @Around("within(com.scedu.service.Impl.*Impl)")
    public  Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        log.info("环绕执行之前的目标方法名："+proceedingJoinPoint.getSignature().getName());
        log.info("目标方法参数："+proceedingJoinPoint.getArgs());
        log.info("目标对象："+proceedingJoinPoint.getTarget());
        Object obj = proceedingJoinPoint.proceed(); //执行放行的方法
        log.info("环绕执行之后的通知");
        return obj;

    }
}

